﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text;

namespace AppFabricAdministrator
{
    public class ScriptHelper
    {
        private static Runspace runspace;
        public static Runspace CurrentRunSpace
        {
            get
            {
                if (runspace == null)
                {
                    runspace = RunspaceFactory.CreateRunspace();
                    runspace.Open();
                }
                return runspace;
            }
        }

        private static PowerShell currentPowerShell;
        public static PowerShell CurrentPowerShell
        {
            get
            {
                if (currentPowerShell == null)
                    currentPowerShell = PowerShell.Create();
                return currentPowerShell;
            }
        }

        public static string RunScript(string scriptText,
            string commandExecutedSuccessText, Func<IEnumerable<PSObject>, string> callBack, out bool isSuccess, bool includeCmd = true)
        {
            StringBuilder result = new StringBuilder();
            try
            {
                CurrentPowerShell.Commands.Clear();
                CurrentPowerShell.AddScript(scriptText);

                if (includeCmd)
                    result.AppendLine(string.Format("Script : {0}", scriptText));
                if (callBack != null)
                    result.AppendLine(callBack(CurrentPowerShell.Invoke()));
                else
                    CurrentPowerShell.Invoke();
                if (includeCmd)
                    result.AppendLine(commandExecutedSuccessText);

                AppfabricAdministrator.WriteScriptOut(result.ToString());
                LogHelper.WriteInfo(result.ToString().Trim());
                isSuccess = true;
            }
            catch (Exception ex)
            {
                result.Append(String.Format("\r\nError in script : {0}\r\n", ex.Message));
                LogHelper.WriteException(ex);
                isSuccess = false;
            }
            return result.ToString();
        }

        public static string RunCommandScript(string scriptText,
            string commandExecutedSuccessText, Func<IEnumerable<PSObject>, string> callBack, out bool isSuccess, bool includeCmd = true)
        {
            StringBuilder result = new StringBuilder();
            try
            {
                CurrentPowerShell.AddScript(scriptText);
                CurrentPowerShell.AddCommand("Out-String");
                if (includeCmd)
                    result.AppendLine(string.Format("Script : {0}", scriptText));
                result.AppendLine(callBack(CurrentPowerShell.Invoke()));
                if (includeCmd)
                    result.AppendLine(commandExecutedSuccessText);
                AppfabricAdministrator.WriteScriptOut(result.ToString());
                LogHelper.WriteInfo(result.ToString().Trim());
                isSuccess = true;
            }
            catch (Exception ex)
            {
                result.Append(String.Format("\r\nError in script : {0}\r\n", ex.Message));
                LogHelper.WriteException(ex);
                isSuccess = false;
            }
            return result.ToString();
        }


        public static string RunNewScript(string scriptText,
                    string commandExecutedSuccessText, Func<IEnumerable<PSObject>, string> callBack, out bool isSuccess, bool includeCmd = true)
        {
            StringBuilder result = new StringBuilder();
            PowerShell shell = PowerShell.Create();
            string initializeScriptText = @"Import-Module DistributedCacheAdministration;Use-CacheCluster";

            try
            {
                shell.AddScript(initializeScriptText);
                shell.AddScript(scriptText);

                if (includeCmd)
                    result.AppendLine(string.Format("Script : {0}", scriptText));
                result.AppendLine(callBack(shell.Invoke()));
                if (includeCmd)
                    result.AppendLine(commandExecutedSuccessText);
                AppfabricAdministrator.WriteScriptOut(result.ToString());
                LogHelper.WriteInfo(result.ToString().Trim());
                isSuccess = true;
            }
            catch (Exception ex)
            {
                result.Append(String.Format("\r\nError in script : {0}\r\n", ex.Message));
                LogHelper.WriteException(ex);
                isSuccess = false;
            }
            return result.ToString();
        }

        public static string ResultToString(IEnumerable<PSObject> results)
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PSObject obj in results)
            {
                stringBuilder.AppendLine(obj.ToString());
            }

            return stringBuilder.ToString().Trim().Trim(new char[] { '\r', '\n', '\t' });
        }

    }
}
